package com.lanxin.interceptor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lanxin.hr.entity.ZzAccount;
import com.lanxin.hr.entity.ZzEmployee;
import com.lanxin.hr.service.IZzEmployeeService;
import com.lanxin.qx.entity.QxFunction;
import com.lanxin.qx.entity.QxRoleFunction;
import com.lanxin.qx.entity.QxRoleUser;
import com.lanxin.qx.service.IQxFunctionService;
import com.lanxin.qx.service.IQxRoleFunctionService;
import com.lanxin.qx.service.IQxRoleUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

public class QxInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private IQxFunctionService qxFunctionService;
    @Autowired
    private IQxRoleFunctionService roleFunctionService;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private IZzEmployeeService employeeService;
    @Autowired
    private IQxRoleUserService roleUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        ZzAccount account = (ZzAccount) session.getAttribute("account");

        //放行管理员
        if(account.getAid()==1){
            return true;
        }

        ZzEmployee employee = null;
        Integer roleId = null;
        if(account != null){
            employee = employeeService.getEmpById(account.getAid());
        }
        if(employee == null){
            response.sendRedirect(request.getContextPath()+"/qxError.jsp");
            return false;
        }
        QxRoleUser qxRoleUser = roleUserService.getOne(new QueryWrapper<QxRoleUser>().eq("eid",employee.getOid()));
        if(qxRoleUser == null){
            response.sendRedirect(request.getContextPath()+"/qxError.jsp");
            return false;
        }
        roleId = qxRoleUser.getRoleid();
        //请求路径
        String path = request.getRequestURI();
        //获取受权限管控的方法
        //由于权限控制需要大量使用，所以将其放入redis中以提升响应速度
        List<Object> functions = new ArrayList<>();
        functions = redisTemplate.opsForHash().values("functions");
        if(functions.isEmpty()){
            response.sendRedirect(request.getContextPath()+"/qxError.jsp");
            return false;
        }
        List<QxFunction> functions2 = new ArrayList<>();
        //将获取到的数据转为QxFunction类
        for (Object function : functions) {
            QxFunction qxFunction = (QxFunction) function;
            functions2.add(qxFunction);
        }
        //遍历方法集合来获取需要验证的方法
        for (QxFunction function : functions2) {
            if(function.getMethod()==null||"".equals(function.getMethod())){
                continue;
            }
            //如果请求被权限控制的方法则需要进行验证,验证当前用户是否有该功能的权限
            if(path.contains(function.getMethod())){
                //根据角色id拿到改角色拥有的功能，
                List<Integer> roleFunctions = new ArrayList<>();
                roleFunctions = roleFunctionService.getFunctionsByRoleId(roleId);
                //先判断该角色所拥有的功能里面是否包含了当前功能，如果有则继续下一步验证，如果没有则直接返回false，跳转到没有权限的提示页面
                if(!roleFunctions.contains(function.getOid())){
                    //若没有方法权限
                    response.sendRedirect(request.getContextPath()+"/qxError.jsp");
                    return false;
                }else {
                    //若改角色包含当前访问的功能，则获取该角色下所拥有的员工，根据员工id判断当前员工是否在该角色下
                    //根据角色id获取员工id
                    List<Integer> emps = new ArrayList<>();
                    emps = roleUserService.getEmpByRoleId(roleId);
                    //若是则放行返回true，若不是则跳转到权限提示页面，返回false
                    if(!emps.contains(employee.getOid())){
                        response.sendRedirect(request.getContextPath()+"/qxError.jsp");
                        return false;
                    }
                }
            }
        }
        return true;
    }
}

